package dao;

import beans.Funcionario;
import java.security.MessageDigest;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class FuncionarioDAO {

    PreparedStatement pst;
    ResultSet rs;

    public FuncionarioDAO() {
    }

    public Funcionario load(String login) {
        Funcionario func = new Funcionario();

        String query = "SELECT * FROM funcionario WHERE login = ?";

        try {
            pst = Conexao.getConexao().prepareStatement(query);
            pst.setString(1, login);
            rs = pst.executeQuery();

            if (rs.next()) {
                func.setCpf(rs.getInt("cpf"));
                func.setNome(rs.getString("nome"));

                func.setLogin(rs.getString("login"));
                func.setSenha(rs.getString("senha"));

                func.setAdmin(rs.getBoolean("admin"));
                func.setPermAnimais(rs.getBoolean("animais"));
                func.setPermFinancas(rs.getBoolean("financas"));
            }

        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException ex) {
                ex.getLocalizedMessage();
            }
        }

        return func;
    }

    public Funcionario load(int cpf) {
        Funcionario func = new Funcionario();

        String query = "SELECT * FROM funcionario WHERE cpf = ?";

        try {
            pst = Conexao.getConexao().prepareStatement(query);
            pst.setInt(1, cpf);
            rs = pst.executeQuery();

            if (rs.next()) {
                func.setCpf(rs.getInt("cpf"));
                func.setNome(rs.getString("nome"));

                func.setLogin(rs.getString("login"));
                func.setSenha(rs.getString("senha"));

                func.setAdmin(rs.getBoolean("admin"));
                func.setPermAnimais(rs.getBoolean("animais"));
                func.setPermFinancas(rs.getBoolean("financas"));
            }

        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException ex) {
                ex.getLocalizedMessage();
            }
        }

        return func;
    }

    public String hashMD5(String senha) {
        String senhaHash = null;

        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(senha.getBytes("UTF-8"));
            byte[] hashBytes = md.digest();

            StringBuilder hash = new StringBuilder();

            for (int i = 0; i < hashBytes.length; i++) {
                int parteAlta = ((hashBytes[i] >> 4) & 0xf) << 4;
                int parteBaixa = hashBytes[i] & 0xf;

                if (parteAlta == 0) {
                    hash.append('0');
                }

                hash.append(Integer.toHexString(parteAlta | parteBaixa));
            }

            senhaHash = hash.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return senhaHash;
    }

    public void insert(Funcionario func) {
        String query = "INSERT INTO funcionario (cpf, login, senha, nome, admin, animais, financas)"
                + " VALUES (?, ?, ?, ?, ?, ?, ?)";

        try {
            pst = Conexao.getConexao().prepareStatement(query);

            pst.setInt(1, func.getCpf());
            pst.setString(2, func.getLogin());
            pst.setString(3, hashMD5(func.getSenha()));
            pst.setString(4, func.getNome());
            pst.setBoolean(5, func.isAdmin());
            pst.setBoolean(6, func.isPermAnimais());
            pst.setBoolean(7, func.isPermFinancas());

            pst.executeUpdate();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException ex) {
                ex.getLocalizedMessage();
            }
        }
    }

    public void update(Funcionario func) {

        String query = "SELECT senha FROM funcionario WHERE cpf = ?";


        try {
            pst = Conexao.getConexao().prepareStatement(query);
            pst.setInt(1, func.getCpf());
            rs = pst.executeQuery();
            rs.next();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }

        query = "UPDATE funcionario"
                + " SET login = ?, senha = ?, nome = ?, admin = ?, animais = ?, financas = ?"
                + " WHERE cpf = ?";

        try {
            pst = Conexao.getConexao().prepareStatement(query);

            pst.setString(1, func.getLogin());

            if (func.getSenha().equals(rs.getString("senha"))) {
                // senha não alterada, NÃO PASSA NOVO HASH
                pst.setString(2, func.getSenha());
            } else {
                pst.setString(2, hashMD5(func.getSenha()));
            }
            pst.setString(3, func.getNome());
            pst.setBoolean(4, func.isAdmin());
            pst.setBoolean(5, func.isPermAnimais());
            pst.setBoolean(6, func.isPermFinancas());
            pst.setInt(7, func.getCpf());
            
            pst.executeUpdate();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException ex) {
                ex.getLocalizedMessage();
            }
        }


    }

    public void save(Funcionario func) {
        if (func.getCpf() == 0) {
            insert(func);
        } else {
            String query = "SELECT COUNT(cpf)"
                    + " FROM funcionario"
                    + " WHERE cpf = ?";
            try {
                pst = Conexao.getConexao().prepareStatement(query);
                pst.setInt(1, func.getCpf());
                rs = pst.executeQuery();

                rs.next();

                if (rs.getInt("count") != 0) {
                    update(func);
                } else {
                    insert(func);
                }

            } catch (SQLException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    if (rs != null) {
                        rs.close();
                    }
                    if (pst != null) {
                        pst.close();
                    }
                } catch (SQLException ex) {
                    ex.getLocalizedMessage();
                }
            }


        }

    }

    public void delete(Funcionario func) {
        String query = "DELETE FROM funcionario WHERE cpf = ?";

        try {
            pst = Conexao.getConexao().prepareStatement(query);

            pst.setInt(1, func.getCpf());

            pst.executeUpdate();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException ex) {
                ex.getLocalizedMessage();
            }
        }
    }

    public ArrayList<Funcionario> loadAll() {
        ArrayList<Funcionario> funcionarios = new ArrayList<Funcionario>();

        String query = "SELECT * FROM funcionario";

        try {
            pst = Conexao.getConexao().prepareStatement(query);
            rs = pst.executeQuery();

            while (rs.next()) {
                Funcionario func = new Funcionario();

                func.setCpf(rs.getInt("cpf"));
                func.setNome(rs.getString("nome"));

                func.setLogin(rs.getString("login"));
                func.setSenha(rs.getString("senha"));

                func.setAdmin(rs.getBoolean("admin"));
                func.setPermAnimais(rs.getBoolean("animais"));
                func.setPermFinancas(rs.getBoolean("financas"));

                funcionarios.add(func);
            }
        } catch (SQLException ex) {
            ex.getLocalizedMessage();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException ex) {
                ex.getLocalizedMessage();
            }
        }

        return funcionarios;
    }
}
